#include "pch.h"

using namespace BaseLogic;

namespace M6502Core
{
	Decoder::Decoder()
	{
		pla = new PLA(inputs_count, outputs_count, (char *)"Decoder6502.bin");

		// The bitmask corresponds to the values from the Breaking NES Wiki:
		// https://github.com/emu-russia/breaks/blob/master/BreakingNESWiki_DeepL/6502/decoder.md

		static size_t bitmask[outputs_count] = {
			// A
			0b000101100000100100000,
			0b000000010110001000100,
			0b000000011010001001000,
			0b010100011001100100000,
			0b010101011010100100000,
			0b010110000001100100000,

			// B
			0b000000100010000001000,
			0b000001000000100010000,
			0b000000010101001001000,
			0b010101011001100010000,
			0b010110011001100010000,
			0b011010000001100100000,
			0b000101000000100010000,
			0b010101011010100010000,
			0b011001000000100010000,
			0b100110011001100010000,
			0b101010011001100100000,
			0b011001011010100010000,
			0b100100011001100100000,
			0b011001100000100100000,
			0b011001000001100100000,

			// C
			0b011001010101010100000,
			0b000101010101010100001,
			0b010100011001010100000,
			0b001010010101010100010,
			0b001000011001010100100,
			0b000110010101010100001,
			0b001010000000010010000,
			0b000000000000000001000,
			0b010110000000011000000,
			0b000010101001010100000,
			0b000000101001000001000,
			0b010101000000011000000,
			0b000000000100000001000,
			0b010000000000000000000,
			0b000000010001010101000,
			0b000000000001010100100,

			// D
			0b000001010101010100010,
			0b000110010101010100010,
			0b000000010101001000100,
			0b000000010110001000010,
			0b000000010110001001000,
			0b000000001010000000100,
			0b001000011001010100000,
			0b001010000000100010000,
			0b000000010101001000010,
			0b000000010110001000100,
			0b000010010101010100000,
			0b001001010101010101000,
			0b010010000001100100000,
			0b010110000000101000000,
			0b011010000000101000000,
			0b011010000000001000000,
			0b001001000000010010000,

			// E
			0b000010101001010100100,
			0b000001000000010010000,
			0b001001010101010100001,
			0b000000010001010101000,
			0b010101011010100100000,
			0b100000000000011000000,
			0b101010000000001000000,
			0b100000011001010010000,
			0b010101011001100010000,
			0b011010011001010100000,
			0b011001000000101000000,
			0b010000000000001000000,
			0b011001011001100100000,
			0b010000011001010010000,
			0b011001011001100010000,
			0b011001100001010100000,
			0b011001000000011000000,
			0b000000001010000000010,
			0b000000010110001000001,

			// F
			0b010000010110000100000,
			0b000110011001010101000,
			0b010010011001010010000,
			0b000010000000010010000,
			0b000101010101010101000,
			0b001001010101010100100,
			0b000101000000101000000,
			0b000000010110000101000,
			0b000000100100000001000,
			0b000000010100001001000,
			0b000000001000000001000,
			0b001010010101010100001,
			0b000000000000000000010,
			0b000000000000000000100,
			0b010100010101010100000,
			0b010010101001010100000,
			0b000000010101001000001,
			0b000000001000000000100,

			// G
			0b000000010110001000010,
			0b000000001010000000100,
			0b000000010110000100100,
			0b000100010101010100000,
			0b001001010101010100000,
			0b000010101001010100000,
			0b000101000000100000000,
			0b000101010101010100010,
			0b000101011001010101000,
			0b000100011001010101000,
			0b000010101001010100010,
			0b000010010101010100001,
			0b001001010101010100001,

			// H
			0b000110101001010101000,
			0b001000011001010100100,
			0b000010000000000010000,
			0b000001000000010010000,
			0b010010011010010100000,
			0b101001100001010100000,
			0b010001011010010100000,
			0b000000100110000000100,
			0b101010000000001000000,
			0b011001100001010100000,
			0b011001011001010100000,
			0b000110010101010100010,
			0b100110000000101000000,
			0b100010101001100100000,
			0b100001011001010010000,
			0b100010000101100100000,

			// K
			0b010010011010100100000,
			0b000001000000000000000,
			0b000000101001000000100,
			0b000000100101000001000,
			0b000000010100001000001,
			0b000000001010000000010,
			0b000000000000010000000,
			0b001001011010100100000,
			0b000000011000000000000,
			0b000000011001010100000,		// pp
		};

		pla->SetMatrix(bitmask);
	}

	Decoder::~Decoder()
	{
		delete pla;
	}

	void Decoder::sim(size_t input_bits, TriState** outputs)
	{
		pla->sim(input_bits, outputs);
	}
}
